import { BullModule } from "@nestjs/bullmq";
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { APP_INTERCEPTOR } from "@nestjs/core";
import { ScheduleModule } from "@nestjs/schedule";
import { ClsModule } from "nestjs-cls";
import { AppController } from "@/app.controller";
import { AppService } from "@/app.service";
import { DatabaseModule } from "@/database/database.module";
import { CreateLogInterceptor } from "./common/interceptors/create-log.interceptor";
import { EsModule } from "./database/es.module";
import { RedisModule } from "./database/redis.module";
import { BaseModule } from "./modules/base.module";

@Module({
    imports: [
        ConfigModule.forRoot({
            isGlobal: true, // 全局注册配置模块，无需在其他模块中重复导入
            cache: true, // 启用缓存以提高性能
            /**
             * 根据环境变量加载不同的配置文件，支持多个文件
             * 踩坑: 官方文档中描述, 将从默认位置（项目根目录）加载和解析 .env 文件
             * 通过 pm2 启动时，发现从 dist 目录加载不到 .env 文件, 导致配置无法生效, 应该将配置文件放在 dist 同级目录下
             * 参考: https://nest.nodejs.cn/techniques/configuration
             */
            envFilePath: [`.env.${process.env.NODE_ENV}`, ".env"],
        }),
        // 参考: https://nest.nodejs.cn/recipes/async-local-storage
        ClsModule.forRoot({
            global: true,
            middleware: {
                mount: true, // 自动为所有路由挂载Cls中间件
            },
        }),
        // BullModule.forRoot({
        //     connection: {
        //         host: process.env.REDIS_HOST,
        //         port: parseInt(process.env.REDIS_PORT || "6379", 10),
        //         password: process.env.REDIS_PASSWORD || undefined,
        //     },
        // }),
        BullModule.forRootAsync({
            imports: [ConfigModule],
            useFactory: (configService: ConfigService) => ({
                connection: {
                    host: configService.get<string>("REDIS_HOST", "localhost"),
                    port: configService.get<number>("REDIS_PORT", 6379),
                    password: configService.get<string>("REDIS_PASSWORD"),
                    db: configService.get<number>("REDIS_DB", 0),
                },
            }),
            inject: [ConfigService],
        }),
        ScheduleModule.forRoot(),
        RedisModule,
        DatabaseModule,
        EsModule,
        BaseModule,
    ],
    controllers: [AppController],
    providers: [
        AppService,
        {
            provide: APP_INTERCEPTOR,
            useClass: CreateLogInterceptor,
        },
    ],
})
export class AppModule {}
